/**
 * Document Processors
 * 
 * 文档解析器 - 支持多种文档格式的解析
 */

import type { DocumentType, DocumentMetadata, DocumentProcessor } from '@/types/knowledge';

/**
 * Markdown 文档处理器
 */
export class MarkdownProcessor implements DocumentProcessor {
  supportedTypes: DocumentType[] = ['markdown'];

  async parse(file: File): Promise<{
    content: string;
    metadata: Partial<DocumentMetadata>;
  }> {
    const content = await this.readFileAsText(file);
    
    return {
      content,
      metadata: {
        filename: file.name,
        fileType: 'markdown',
        fileSize: file.size,
        mimeType: file.type,
        characterCount: content.length,
        createdAt: new Date(file.lastModified),
      },
    };
  }

  async validate(file: File): Promise<{ valid: boolean; error?: string }> {
    if (!file.name.match(/\.(md|markdown)$/i)) {
      return {
        valid: false,
        error: '文件必须是 Markdown 格式 (.md 或 .markdown)',
      };
    }

    if (file.size > 10 * 1024 * 1024) {
      return {
        valid: false,
        error: '文件大小不能超过 10MB',
      };
    }

    return { valid: true };
  }

  private async readFileAsText(file: File): Promise<string> {
    return new Promise((resolve, reject) => {
      const reader = new FileReader();
      reader.onload = () => resolve(reader.result as string);
      reader.onerror = reject;
      reader.readAsText(file);
    });
  }
}

/**
 * 纯文本文档处理器
 */
export class TextProcessor implements DocumentProcessor {
  supportedTypes: DocumentType[] = ['text'];

  async parse(file: File): Promise<{
    content: string;
    metadata: Partial<DocumentMetadata>;
  }> {
    const content = await this.readFileAsText(file);
    
    return {
      content,
      metadata: {
        filename: file.name,
        fileType: 'text',
        fileSize: file.size,
        mimeType: file.type || 'text/plain',
        characterCount: content.length,
        createdAt: new Date(file.lastModified),
      },
    };
  }

  async validate(file: File): Promise<{ valid: boolean; error?: string }> {
    if (!file.name.match(/\.txt$/i) && !file.type.startsWith('text/')) {
      return {
        valid: false,
        error: '文件必须是纯文本格式 (.txt)',
      };
    }

    if (file.size > 10 * 1024 * 1024) {
      return {
        valid: false,
        error: '文件大小不能超过 10MB',
      };
    }

    return { valid: true };
  }

  private async readFileAsText(file: File): Promise<string> {
    return new Promise((resolve, reject) => {
      const reader = new FileReader();
      reader.onload = () => resolve(reader.result as string);
      reader.onerror = reject;
      reader.readAsText(file);
    });
  }
}

/**
 * 代码文件处理器
 */
export class CodeProcessor implements DocumentProcessor {
  supportedTypes: DocumentType[] = ['code'];

  private codeExtensions = [
    '.js', '.ts', '.jsx', '.tsx',
    '.py', '.java', '.cpp', '.c', '.h',
    '.go', '.rs', '.rb', '.php',
    '.html', '.css', '.scss',
    '.json', '.yaml', '.yml',
    '.sh', '.bash',
  ];

  async parse(file: File): Promise<{
    content: string;
    metadata: Partial<DocumentMetadata>;
  }> {
    const content = await this.readFileAsText(file);
    const language = this.detectLanguage(file.name);
    
    return {
      content,
      metadata: {
        filename: file.name,
        fileType: 'code',
        fileSize: file.size,
        mimeType: file.type,
        characterCount: content.length,
        language,
        createdAt: new Date(file.lastModified),
      },
    };
  }

  async validate(file: File): Promise<{ valid: boolean; error?: string }> {
    const hasValidExtension = this.codeExtensions.some(ext =>
      file.name.toLowerCase().endsWith(ext)
    );

    if (!hasValidExtension) {
      return {
        valid: false,
        error: `不支持的代码文件格式。支持的格式：${this.codeExtensions.join(', ')}`,
      };
    }

    if (file.size > 5 * 1024 * 1024) {
      return {
        valid: false,
        error: '代码文件大小不能超过 5MB',
      };
    }

    return { valid: true };
  }

  private async readFileAsText(file: File): Promise<string> {
    return new Promise((resolve, reject) => {
      const reader = new FileReader();
      reader.onload = () => resolve(reader.result as string);
      reader.onerror = reject;
      reader.readAsText(file);
    });
  }

  private detectLanguage(filename: string): string {
    const ext = filename.toLowerCase().match(/\.([^.]+)$/)?.[1];
    const languageMap: Record<string, string> = {
      js: 'JavaScript',
      ts: 'TypeScript',
      jsx: 'JavaScript (JSX)',
      tsx: 'TypeScript (TSX)',
      py: 'Python',
      java: 'Java',
      cpp: 'C++',
      c: 'C',
      h: 'C/C++ Header',
      go: 'Go',
      rs: 'Rust',
      rb: 'Ruby',
      php: 'PHP',
      html: 'HTML',
      css: 'CSS',
      scss: 'SCSS',
      json: 'JSON',
      yaml: 'YAML',
      yml: 'YAML',
      sh: 'Shell',
      bash: 'Bash',
    };
    return ext ? languageMap[ext] || ext.toUpperCase() : 'Unknown';
  }
}

/**
 * 文档处理器工厂
 */
export class DocumentProcessorFactory {
  private processors: Map<DocumentType, DocumentProcessor> = new Map();

  constructor() {
    this.registerProcessor(new MarkdownProcessor());
    this.registerProcessor(new TextProcessor());
    this.registerProcessor(new CodeProcessor());
  }

  /**
   * 注册处理器
   */
  registerProcessor(processor: DocumentProcessor): void {
    processor.supportedTypes.forEach(type => {
      this.processors.set(type, processor);
    });
  }

  /**
   * 获取处理器
   */
  getProcessor(file: File): DocumentProcessor | null {
    // 根据文件扩展名判断类型
    const ext = file.name.toLowerCase().match(/\.([^.]+)$/)?.[1];
    
    if (!ext) {
      // 如果没有扩展名，尝试根据 MIME 类型
      if (file.type.startsWith('text/')) {
        return this.processors.get('text') || null;
      }
      return null;
    }

    // Markdown
    if (['md', 'markdown'].includes(ext)) {
      return this.processors.get('markdown') || null;
    }

    // Text
    if (ext === 'txt') {
      return this.processors.get('text') || null;
    }

    // Code
    const codeExtensions = [
      'js', 'ts', 'jsx', 'tsx',
      'py', 'java', 'cpp', 'c', 'h',
      'go', 'rs', 'rb', 'php',
      'html', 'css', 'scss',
      'json', 'yaml', 'yml',
      'sh', 'bash',
    ];
    if (codeExtensions.includes(ext)) {
      return this.processors.get('code') || null;
    }

    return null;
  }

  /**
   * 获取支持的文件类型列表
   */
  getSupportedTypes(): DocumentType[] {
    return Array.from(this.processors.keys());
  }

  /**
   * 检查文件是否支持
   */
  isSupported(file: File): boolean {
    return this.getProcessor(file) !== null;
  }

  /**
   * 解析文档
   */
  async parse(file: File): Promise<{
    content: string;
    metadata: Partial<DocumentMetadata>;
  }> {
    const processor = this.getProcessor(file);
    if (!processor) {
      throw new Error(`不支持的文件类型: ${file.name}`);
    }

    // 验证文件
    const validation = await processor.validate(file);
    if (!validation.valid) {
      throw new Error(validation.error || '文件验证失败');
    }

    // 解析文件
    return processor.parse(file);
  }
}

/**
 * 单例实例
 */
let factoryInstance: DocumentProcessorFactory | null = null;

/**
 * 获取文档处理器工厂实例
 */
export function getDocumentProcessorFactory(): DocumentProcessorFactory {
  if (!factoryInstance) {
    factoryInstance = new DocumentProcessorFactory();
  }
  return factoryInstance;
}

